package cndw.core.dispatch.executor;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;

/**
 * 
 * @author zuojie.x
 */
public class ActionExecutor<T extends ActionTask> {
	int id;
	final LinkedBlockingDeque<T> taskQueue = null;
	ConcurrentHashMap<String, Object> playerMap = null;
	Object obj = new Object();
	ExecutorService executorService = Executors.newSingleThreadExecutor();
	
	void remove(String playerId) {
		playerMap.remove(playerId);
	}
	
	void execute(T t) {
		taskQueue.offer(t);
		playerMap.putIfAbsent(t.getPlayerId(), obj);
		execute();
	}
	
	void executeFirst(T t) {
		taskQueue.offerFirst(t);
		playerMap.putIfAbsent(t.getPlayerId(), obj);
		execute();
	}
	
	void execute() {
		executorService.execute(new Runnable() {
			@Override
			public void run() {
				T t = null;
				while ((t = taskQueue.poll()) != null) {
					synchronized (t.getPlayerId().intern()) {
						try {
							t.run();
						} catch (Exception e) {
							e.printStackTrace();
						}
						t = null;
					}
				}
			}
		});
	}
	
	int playerSize() {
		return playerMap.keySet().size();
	}
}
